home *** CD-ROM | disk | FTP | other *** search
-
- .386p
- code32 segment para public use32
- assume cs:code32,ds:code32
- include 386power.inc
- include chario.inc
- include 386video.inc
- include 386keyb.inc
- include pix.inc
-
- ; include common menu definitions
- include 386mnu.inc
-
- INPUT_ON macro
- mov edi,_CHRMENU2
- mov _CHRFNT,edi
- endm
-
- INPUT_OFF macro
- mov edi,_CHRMENU1
- mov _CHRFNT,edi
- endm
-
- E_NAME =4
- E_VALUE =8
- E_FN =12
- E_MIN =16
- E_MAX =20
- E_STEP =24
-
- ; Header: text menu title
- ;
- ; db M_HEADER,t_col,maxwidth,touchngo
- ; dd text_p,x,y
- ;
- ; x,y = initial position IN PIXELS of the upper left border
- ; of this menu, or -1,-1 if the menu manager can freely choose
- ; where popup these.
- ; N.B. if x,y are out of range or the menu manager supports
- ; popup menu repositioning, these values will be
- ; modified by the menu manager.
- ; t_col = column position of entry name
- ; text_p = code32 offset to asciiz string to show starting from
- ; t_col column.
- ; maxwidth = maximum menu width in characters
- ; touchngo: 0=only ESC or an "exit" entry will end this menu
- ; 1=AFTER the first SELECTION, end this menu
- ; (useful for the "save game" or "load game" menu)
-
- EB_T_COL =1
- EB_MAXW =2
- EB_TNG =3
- sho_name:
- mov edx,[ecx*4+ENTRY_ROW]
- mov eax,_VDispX
- mov esi,[ecx*4+ENTRY_DATA]
- mov edi,_ScrBase
- movzx ebp,byte ptr [esi+EB_T_COL]
- add edx,_VDispY
- mov ebx,[esi+E_NAME]
- lea eax,[eax+ebp*8+16]
- call _PutString
- ret
-
- name_show:
- ;ecx = current entry index
- pushad
- call sho_name
- popad
- ret
-
-
- ; Bar: text <-]#############[+> a "volume level" bar
- ;
- ; db M_BAR,t_col,in_col,in_len
- ; dd text_p, value_p, func_p,min, max, step
- ;
- ; in_col = colum position of the "volume level bar"
- ; starting with the <-] character
- ; in_len = lenght of the "volume bar" (excluding the <-] and [+> characters)
- ; value_p = code32 offset to the variable containing the value to show/set
- ; min = minimum allowed value
- ; max = maximum allowed value
- ; func_p = code32 offset of function to call every time the entry value
- ; is altered (use this for value checking/correction
- ; or to trigger special actions depending on the value )
- ; Function parameters:
- ; in:
- ; Segment registers pointing to the usual 386P segments.
- ; EAX = value "requested by user"
- ; to set into the variable pointed by value_p
- ; out:
- ; EAX = ALLOWED value to store into the variable
- ; (the menu manager will store it properly)
- ; IF CARRY SET, REFRESH ALL THE DISPLAYED DATA
- ; All other registers preserved.
- ;
- ; step = increment/decrement step for the variable pointed by value_p
- ;
-
- udec: ; bar and unsigned integers
- bdec:
- ; ecx = current entry index
- mov esi,[ecx*4+ENTRY_DATA]
- mov ebx,[esi+E_VALUE]
- mov eax,[ebx]
- mov edx,[esi+E_MIN]
- mov ebp,[esi+E_STEP]
- sub eax,edx
- jnb gb_min
- cut_down:
- mov eax,edx
- jmp short gb_checked
- gb_min:
- sub eax,ebp
- jb cut_down
- add eax,edx
- jmp short gb_checked
-
- uinc: ; bar and unsigned integers
- binc:
- ; ecx = current entry index
- mov esi,[ecx*4+ENTRY_DATA]
- mov ebx,[esi+E_VALUE]
- mov edx,[esi+E_MAX]
- mov ebp,[esi+E_STEP]
- mov eax,[ebx]
- add eax,ebp
- sub eax,edx
- jb gb_max
- xor eax,eax
- gb_max:
- add eax,edx
- gb_checked:
- xor edx,edx
- call [esi+E_FN]
- mov dl,[esi] ; menu type
- mov [ebx],eax
- jnc gb_rfr
- mov eax,ENTRY_DATA
- call m_refresh
- gb_rfr:
- jmp dword ptr [edx*4+SHOW] ;chain-call
-
- EB_IN_COL =2
- EB_IN_LEN =3
-
- bstring db 40 dup(0)
- bshow:
- ;ecx = current entry index
- push ecx
- call sho_name
- mov edx,[esi+E_VALUE]
- xor ebx,ebx
- mov eax,[edx]
- mov ebp,[esi+E_MIN]
- mov bl,[esi+EB_IN_LEN]
- mov edi,[esi+E_MAX]
- cmp eax,edi
- jbe low_enough
- mov [edx],edi
- mov eax,edi
- low_enough:
- shl ebx,3 ; multiply by 8 to get pixel lenght
- sub eax,ebp
- jnbe high_enough
- mov [edx],ebp ; round to minimum
- mov eax,ebp ;
- high_enough:
- sub edi,ebp
- mul ebx
- div edi
- ; eax=bar level in pixels
- ; ebx=bar maximum bar level in pixels
- mov edi,offset bstring
- shr ebx,3 ; back to "characters"
- mov edx,eax
- mov byte ptr [edi],ARROW_MINUS
- lupp:
- inc edi
- sub eax,8
- jbe outlevel
- mov byte ptr [edi],BAR8
- dec ebx
- jmp short lupp
- outlevel:
- add eax,8
- jne goodbar
- mov al,BAR0 ; we have to avoid NULs
- goodbar:
- mov [edi],al
- empbar:
- inc edi
- dec ebx
- je outbarr
- mov byte ptr [edi],BAR0
- jmp short empbar
- outbarr:
- mov edx,[ecx*4+ENTRY_ROW]
- mov word ptr [edi],ARROW_PLUS ; fancy trick, the high byte is NUL
- mov ebx, offset bstring
- mov eax,_VDispX
- add edx,_VDispY
- movzx ebp,byte ptr [esi+EB_IN_COL]
- mov edi,_ScrBase
- lea eax,[eax+ebp*8+16]
- call _PutString
- pop ecx
- ret
-
- ; Int: text <-]_____________[+> a 32bit integer value
- ;
- ; db M_INT,t_col,in_col,idigits
- ; dd text_p, value_p, func_p, min, max, step
- ;
- ; idigits = maximum number of digits including optional sign character
-
- EB_IDIGITS=3
-
- isel:
- xor eax,eax
- mov edx,[ecx*4+ENTRY_ROW]
- mov esi,[ecx*4+ENTRY_DATA]
- push ecx
- add edx,_VDispY
- xor ecx,ecx
- mov al,[esi+EB_IN_COL]
- mov ebx,[esi+E_VALUE]
- shl eax,3 ; multiply by 8
- mov cl,[esi+EB_IDIGITS]
- push ebx
- INPUT_ON
- add eax,_VDispX
- mov ebx,[ebx]
- mov edi,_ScrBase
- add eax,16
- call _GetInt
- mov eax,ebx ; copy returned value
- INPUT_OFF
- pop ebx
- pop ecx
- jmp icheck
-
-
- idec:
- ; ecx = current entry index
- mov esi,[ecx*4+ENTRY_DATA]
- mov ebx,[esi+E_VALUE]
- mov eax,[ebx]
- sub eax,[esi+E_STEP]
- jmp short icheck
-
- iinc:
- ; ecx = current entry index
- mov esi,[ecx*4+ENTRY_DATA]
- mov ebx,[esi+E_VALUE]
- mov eax,[ebx]
- add eax,[esi+E_STEP]
- icheck:
- cmp eax,[esi+E_MIN]
- jnl gi_min
- mov eax,[esi+E_MIN]
- gi_min:
- cmp eax,[esi+E_MAX]
- jle gi_max
- mov eax,[esi+E_MAX]
- gi_max:
- call [esi+E_FN]
- mov [ebx],eax
- jnc gi_rfr
- mov eax,ENTRY_DATA
- call m_refresh
- gi_rfr:
- ; chain-call to ishow
-
- ushow:
- ishow:
- ;ecx = current entry index
- push ecx
- call sho_name
- xor ebx,ebx
- mov edx,[ecx*4+ENTRY_ROW]
- xor ecx,ecx
- mov bx,[esi+EB_IN_COL]
- INPUT_ON
- mov eax,_VDispX
- xchg cl,bh ; cl = EB_IDIGITS
- add edx,_VDispY
- mov ebp,[esi+E_VALUE]
- lea eax,[eax+ebx*8+16]
- mov edi,_ScrBase
- mov ebx,ds:[ebp]
- cmp byte ptr [esi],M_INT
- jne is_unsigned
- call _PutInt
- INPUT_OFF
- pop ecx
- ret
- is_unsigned:
- call _PutUnsigned
- INPUT_OFF
- pop ecx
- ret
-
- ;
- ; Unsigned: text <-]_____________[+> a 32bit dword value
- ;
- ; db M_UNSIGNED,t_col,in_col,udigits
- ; dd text_p, value_p, func_p, min, max, step
- ;
- ; udigits = maximum number of digits (and no sign)
-
- ; ushow is included with ishow
- ; uinc and udec are the same as bdec and dinc
-
- usel:
- xor eax,eax
- mov edx,[ecx*4+ENTRY_ROW]
- mov esi,[ecx*4+ENTRY_DATA]
- push ecx
- add edx,_VDispY
- xor ecx,ecx
- INPUT_ON
- mov al,[esi+EB_IN_COL]
- mov ebx,[esi+E_VALUE]
- shl eax,3 ; multiply by 8
- mov cl,[esi+EB_IDIGITS]
- add eax,_VDispX
- mov ebx,[ebx]
- mov edi,_ScrBase
- add eax,16
- call _GetUnsigned
- mov eax,ebx ; copy returned value
- INPUT_OFF
- pop ecx
- mov ebx,[esi+E_VALUE]
- mov edx,[esi+E_MIN]
- mov ebp,[esi+E_MAX]
- cmp eax,edx
- jnb gb_mgo
- mov eax,edx
- gb_mgo:
- cmp eax,ebp
- jb gb_go
- mov eax,ebp
- gb_go:
- jmp gb_checked
-
- ;
- ; Pick_list: text <-]_____________[+> choose from a list
- ;
- ; db M_PICK,t_col,in_col,max_item_len
- ; dd text_p, value_p, func_p,picklist_p, picktop
- ;
- ; max_item_len = maximum lenght in characters of the strings
- ; pointed by the "pick list" table
- ; EVERY string into the pick-list must have this lenght
- ; (with "padding" spaces if the text is shorter
- ; and excluding the final NUL from the count).
- ;
- ; value_p = pointer to a dword with values ranging
- ; from 0 (for the first picklist string)
- ; to picktop-1 (for the last picklist string).
- ; picklist_p = pointer to an array of pointers (all code32 offsets)
- ; to strings describing the "values" you can choose]
- E_PICKLIST = 16
- E_PICKTOP = 20
-
- pdec:
- ; ecx = current entry index
- mov esi,[ecx*4+ENTRY_DATA]
- mov ebx,[esi+E_VALUE]
- mov eax,[ebx]
- or eax,eax
- jz pick_good
- dec eax
- jmp short pcheck
-
- pinc:
- ; ecx = current entry index
- mov esi,[ecx*4+ENTRY_DATA]
- mov ebx,[esi+E_VALUE]
- mov eax,[ebx]
- inc eax
- pcheck:
- cmp eax,[esi+E_PICKTOP]
- jb pick_good
- mov eax,[esi+E_PICKTOP]
- dec eax
- pick_good:
- call [esi+E_FN]
- mov [ebx],eax
- jnc pick_rfr
- mov eax,ENTRY_DATA
- call m_refresh
- pick_rfr:
- ; chain call to pshow
- pshow:
- ;ecx = current entry index
- push ecx
- call sho_name
- mov ebx,[esi+E_VALUE]
- mov edx,[ecx*4+ENTRY_ROW]
- movzx ebp,byte ptr [esi+EB_IN_COL]
- INPUT_ON
- mov eax,_VDispX
- add edx,_VDispY
- mov ebx,[ebx]
- mov esi,[esi+E_PICKLIST]
- mov edi,_ScrBase
- lea eax,[eax+ebp*8+16]
- mov ebx,[esi+ebx*4] ; load pointer to string to display
- call _PutString
- INPUT_OFF
- pop ecx
- ret
-
- ; String: text _____________ string entry
- ;
- ; db M_STRING,t_col,in_col,max_string_characters
- ; dd text_p, value_p, sfunc_p
- ;
- ; function to call to check string, it is like func_p
- ; but eax is a POINTER to the actual string data
- ; and you cannot modify it!!!!!!!
- ssel:
- mov edx,[ecx*4+ENTRY_ROW]
- mov esi,[ecx*4+ENTRY_DATA]
- push ecx
- INPUT_ON
- mov eax,_VDispX
- xor ecx,ecx
- add edx,_VDispY
- movzx ebp,byte ptr[esi+EB_IN_COL]
- mov ebx,[esi+E_VALUE]
- mov cl,[esi+EB_IDIGITS]
- mov edi,_ScrBase
- lea eax,[eax+ebp*8+16]
- call _GetString
- INPUT_OFF
- pop ecx
- mov eax,[esi+E_VALUE]
- call [esi+E_FN]
- jnc str_rfr
- mov eax,ENTRY_DATA
- call m_refresh
- str_rfr:
- ; show it
- sshow:
- ;ecx = current entry index
- push ecx
- ; first of all, execute a row refresh
- mov esi,DARK6_TEXT+(DARK6_TEXT shl 8)+(DARK6_TEXT shl 16)+(DARK6_TEXT shl 24)
- mov eax,_VDispX
- mov ebx,8
- mov edx,_VDispY
- add eax,16 ; skip the cursor columns
- push ecx
- add edx,[ecx*4+ENTRY_ROW]
- mov edi,_ScrBase
- mov ecx,38*2
- call _Block ; set background
- pop ecx
- ; menu name
- call sho_name
- ; string value
- INPUT_ON
- mov edx,[ecx*4+ENTRY_ROW]
- movzx ebp,byte ptr [esi+EB_IN_COL]
- mov eax,_VDispX
- add edx,_VDispY
- mov ebx,[esi+E_VALUE]
- lea eax,[eax+ebp*8+16]
- mov edi,_ScrBase
- call _PutString
- INPUT_OFF
- pop ecx
- ret
-
- ; Submenu: text call a submenu
- ;
- ; db M_MENU,t_col,thru,m_disable
- ; dd text_p, menu_p
- ;
- ; menu_p = code32 offset of M_HEADER entry of menu to call
- ; when this entry is clicked.
- ; thru : 0 = when returning, reactivate this menu and refresh screen
- ; 1 = when returning, quit this menu automatically.
- ; m_disable: 0 = submenu can be selected
- ; 1 = this submenu cannot be activated
-
- EB_THRU =2
- EB_DISABLE =3
- msel:
- mov eax,ENTRY_DATA ; get header address
- mov esi,[ecx*4+ENTRY_DATA]
- push eax
- push ecx
- cmp byte ptr [esi+EB_DISABLE],0
- jne old_menu
- mov eax,[esi+E_VALUE]
- call _PopMenu
- cmp byte ptr [esi+EB_THRU],0
- je old_menu
- pop ecx
- pop eax
- pop ebx ; discard return address
- ; menu termination
- popad
- pop _CHRFNT
- ret
-
- old_menu:
- pop ecx
- pop eax
- pushad
- call m_refresh
- popad
- ret
-
-
- ; Call: text call a subroutine
- ;
- ; db M_CALL,t_col,thru,0
- ; dd text_p, procedure_p
- ;
- ; procedure_p = code32 offset of code to call
- ; when this entry is clicked.
- ; The function assumes cs=_SelCode, ds=es=ss=fs=_SelData
- ; gs=_SelZero, like the _PopMenu procedure.
- ; The called procedure must preserve all registers.
- ;
- csel:
- mov eax,ENTRY_DATA ; get header address
- mov esi,[ecx*4+ENTRY_DATA]
- push _CHRFNT
- push eax
- call dword ptr [esi+E_VALUE]
- cmp byte ptr [esi+EB_THRU],0
- je old_call
- pop eax
- pop _CHRFNT
- pop ebx ; discard return address
- ; menu termination
- popad
- pop _CHRFNT
- ret
-
- old_call:
- pop eax
- pop _CHRFNT
- call m_refresh
- ret
-
- ; Toggle: [] text boolean entry
- ;
- ; db M_TOGGLE,t_col,flag_col,0
- ; dd text_p, bool_p, func_p
- ;
- ; flag_col = column position of '[]' on/off character
- ; bool_p = pointer to BYTE that can be toggled to 0 or to 1
- ; when clicking on this entry.
- ;
- align byte
- TOGGLES db FLAG_OFF,0,FLAG_ON,0
-
- togg:
- ; ecx = current entry index
- mov esi,[ecx*4+ENTRY_DATA]
- mov ebx,[esi+E_VALUE]
- mov al,[ebx]
- inc al
- tcheck:
- and al,1
- call [esi+E_FN]
- mov [ebx],al
- jnc tg_rfr
- mov eax,ENTRY_DATA
- call m_refresh
- tg_rfr:
- ; chain call to tshow
- tshow:
- ;ecx = current entry index
- push ecx
- ; menu name
- call sho_name
- ; toggle value
- mov edx,[ecx*4+ENTRY_ROW]
- xor ebx,ebx
- mov edi,[esi+E_VALUE]
- movzx ebp,byte ptr [esi+EB_IN_COL]
- mov eax,_VDispX
- mov bl,[edi]
- add edx,_VDispY
- lea eax,[eax+ebp*8+16]
- lea ebx,[ebx*2+TOGGLES]
- mov edi,_ScrBase
- call _PutString
- pop ecx
- ret
-
- ; Key: text keytext keyboard key value
- ;
- ; db M_KEY,t_col,key_col,0
- ; dd text_p, key_p, func_p
- ;
- ; key_col = column position of TEXT (obtained from _KeyNames)
- ; describing the key.
- ; key_p = pointer to BYTE that contains key code
- ;
-
- ksel: mov esi,[ecx*4+ENTRY_DATA]
- mov edx,[ecx*4+ENTRY_ROW]
- mov ebx,[esi+E_VALUE]
- mov ebp,[esi+E_FN]
- mov byte ptr [ebx],0
- push eax ; dummy push
- ooh_retry:
- pop eax ; discard flags if retried
- call kshowinput
- call entry_refresh
- pushad
- call _ScanKeyb
- mov edi,eax ; clear keyboard table
- mov ecx,32 ;
- xor eax,eax ;
- rep stosd ;
- popad
- wait_release:
- call _ScanKeyb
- mov ebx,eax ;key table pointer
- mov eax,1 ;key index (0 is NUL, so skip it)
- kscanning:
- cmp byte ptr [ebx+eax],KPRESSED
- jne nkukkato
- push ecx
- mov byte ptr [ebx+eax],0
- mov ecx,_KeyNames
- mov ecx,[ecx+eax*4]
- cmp ecx,_NotAKey
- pop ecx
- jne kukkato ; it is a known key
- nkukkato:
- inc eax ; increase index
- cmp eax,128
- jb kscanning
- jmp short wait_release
- kukkato:
- call ebp
- pushfd ;save flags
- or eax,eax
- jz ooh_retry ; a NUL entry is not allowed
- mov ebx,[esi+E_VALUE]
- mov [ebx],al
- popfd
- ; chain call to kshow
- jnc ky_rfr
- mov eax,ENTRY_DATA
- call m_refresh
- ky_rfr:
-
- kshow:
- ;ecx = current entry index
- pushad
- ; first of all, execute a row refresh
- mov esi,DARK6_TEXT+(DARK6_TEXT shl 8)+(DARK6_TEXT shl 16)+(DARK6_TEXT shl 24)
- mov eax,_VDispX
- mov ebx,8
- mov edx,_VDispY
- add eax,16 ; skip the cursor columns
- push ecx
- add edx,[ecx*4+ENTRY_ROW]
- mov edi,_ScrBase
- mov ecx,38*2
- call _Block ; set background
- pop ecx
- ; menu name
- call sho_name
- ; key's value
- INPUT_ON
- mov esi,[ecx*4+ENTRY_DATA]
- mov ebx,[esi+E_VALUE]
- movzx ebp,byte ptr [esi+EB_IN_COL]
- mov eax,_VDispX
- mov edx,_VDispY
- movzx ebx,byte ptr [ebx]
- mov edi,_ScrBase
- lea eax,[eax+ebp*8+16]
- shl ebx,2
- add edx,[ecx*4+ENTRY_ROW]
- add ebx,_KeyNames
- mov ebx,[ebx]
- call _PutString
- INPUT_OFF
- popad
- ret
-
- pressakey db 'press a key',0
-
- kshowinput: ; "show key entry" for input
- ;ecx = current entry index
- pushad
- ; first of all, execute a row refresh
- mov esi,DARK6_TEXT+(DARK6_TEXT shl 8)+(DARK6_TEXT shl 16)+(DARK6_TEXT shl 24)
- mov eax,_VDispX
- mov ebx,8
- mov edx,_VDispY
- add eax,16 ; skip the cursor columns
- push ecx
- add edx,[ecx*4+ENTRY_ROW]
- mov edi,_ScrBase
- mov ecx,38*2
- call _Block ; set background
- pop ecx
- ; menu name
- call sho_name
- ; "press a key"
- INPUT_ON
- mov esi,[ecx*4+ENTRY_DATA]
- movzx ebp,byte ptr [esi+EB_IN_COL]
- mov eax,_VDispX
- mov edx,_VDispY
- mov edi,_ScrBase
- lea eax,[eax+ebp*8+16]
- add edx,[ecx*4+ENTRY_ROW]
- mov ebx,offset pressakey
- call _PutString
- INPUT_OFF
- popad
- ret
-
- ; Exit: text "exit from this menu"
- ;
- ; db M_EXIT,t_col,0,0
- ; dd exit_text_p
- ;
- ; exit_text_p = pointer to the entry name
- ; (for example: 'CONTINUE GAME',0)
- ;
- xsel:
- pop eax ; discard return address
- popad
- pop _CHRFNT
- ret
-
- ; End: etext end menu marker
- ; etext with optional text
- ; ....
- ; etext
- ;
- ;
- ; db M_END,t_col,t_lines,0
- ; dd etext_p
- ;
- ; t_lines = lines of text/string count of strings pointed by etext_p
- ;
- ; etext_p = pointer to a table of pointers to asciiz text strings
- ; to show on the bottom of the menu
- ; if ( etext_p == 0 ) then no text
- ; For example:
- ; if etext_p contains offset menu_usage
- ; and t_lines contains 4
- ; and there is:
- ;
- ; menu_usage dd e0,e1,e2,e3,e4,e5
- ;
- ; e0 db ' HOW',0
- ; e1 db ' MANY',0
- ; e2 db ' LINES',0
- ; e3 db 'YOU',0
- ; e4 db 'WILL',0
- ; e5 db ' SEE?',0
- ;
- ; You will see on the bottom of the menu:
- ; HOW
- ; MANY
- ; LINES
- ; YOU
- ;
- ; (the other strings are not displayed)
-
- EB_T_LINES =2
-
- eshow: push ecx
- mov edx,[ecx*4+ENTRY_ROW]
- mov eax,_VDispX
- mov esi,[ecx*4+ENTRY_DATA]
- mov edi,_ScrBase
- movzx ebx,byte ptr [esi+EB_T_COL]
- add edx,_VDispY
- movzx ebp,byte ptr [esi+EB_T_LINES]
- lea eax,[eax+ebx*8+16]
- mov esi,[esi+E_NAME]
- nxstring:
- mov ebx,[esi]
- add esi,4
- call _PutString
- add edx,8
- dec ebp
- jnz nxstring
- pop ecx
- ret
-
- none:
- ret
-
- no_more_cursor db ' ',0
-
- uup:
- cmp ecx,1
- jbe noo_id
- mov ebp,-1
- jmp short pulisci
- dnn:
- cmp ecx,ENTRIES
- jnb noo_id
- mov ebp,+1
- pulisci:
- push ecx
- mov eax,0
- mov edx,[ecx*4+ENTRY_ROW]
- mov ebx,8
- mov ecx,4
- mov edi,_ScrBase
- call _TouchBlock
- mov eax,_VDispX
- mov ebx,offset no_more_cursor
- add edx,_VDispY
- mov edi,_ScrBase
- call _PutString
- pop ecx
- add ecx,ebp
- noo_id: ret
-
- align byte
- ; M_HEADER M_BAR M_INT M_UNSIGNED M_PICK M_STRING M_MENU M_CALL M_TOGGLE M_KEY M_EXIT M_END
- ENTRY_SIZE db 4*4, 7*4, 7*4, 7*4, 6*4, 4*4, 3*4, 3*4, 4*4, 4*4, 2*4, 2*4
- align dword
- INCREMENT dd none, binc, iinc, uinc, pinc, none, none, none, togg, none, none, none
- DECREMENT dd none, bdec, idec, udec, pdec, none, none, none, togg, none, none, none
- SELECT dd none, none, isel, usel, none, ssel, msel, csel, none, ksel, xsel, none
- UPP dd none, uup, uup, uup, uup, uup, uup, uup, uup, uup, uup, none
- DDN dd none, dnn, dnn, dnn, dnn, dnn, dnn, dnn, dnn, dnn, dnn, none
- SHOW dd name_show,bshow,ishow,ushow, pshow, sshow, name_show,name_show,tshow, kshow, name_show, eshow
-
- ENTRY_DATA dd 25 dup(0)
- ENTRY_ROW dd 25 dup(0)
- ENTRIES dd 0 ; "active" entries (excluding m_header and m_end)
-
- align byte
- ; empty string to clean screen
- zapper db ' ',0
-
- tfe db '386MENU: Too few menu entries, need at least a menu exit option',CR,LF,'$'
- too_few_entries:
- mov _386Return,offset tfe
- jmp _Exit
-
- tmm db '386MENU: Too many menu entries',CR,LF,'$'
- too_many_entries:
- mov _386Return,offset tmm
- jmp _Exit
-
- touchngo db 0
-
- m_refresh: ; refresh menu data structures and screen image
- ; eax= ptr to menu description
- pushad
- mov dl,byte ptr [eax+EB_TNG]
- xor ebp,ebp
- xor ebx,ebx
- mov touchngo,dl
- mov edi,offset ENTRY_DATA
- xor edx,edx
- again:
- mov bl,[eax]
- stosd ; data entry position
- mov dl,[ebx+ENTRY_SIZE]
- inc ebp
- add eax,edx
- cmp bl,M_END
- jne again
- cmp ebp,23 ; 25 lines - 2 interlines == 23 entries max.
- ja too_many_entries
- sub eax,edx ; back to last entry
- xor edx,edx
- sub ebp,2 ; "valid entries" count
- jbe too_few_entries
- mov ebx,22 ; 25 - 1_title_row - 2_interlines
- mov dl,[eax+EB_T_LINES] ; get lines of ending text
- sub ebx,edx ; available_entries - bottom_menu_text
- shl edx,3 ; pixel-lines of text
- push edx ;save lines of text in the end
- ; now calculate menu row positions
- shl ebx,3 ; get value in pixels
- mov ENTRIES,ebp ; save "valid entries" count
- xor edx,edx
- mov eax,ebx ; divide available lines by entries
- div ebp ;
- cmp eax,8
- jb too_many_entries ; less than 8 lines for entry? are you nuts?
- mov ebx,eax ; copy
- shr eax,1 ; divide by two
- mov edi,offset ENTRY_ROW
- mov ecx,ENTRIES
- add eax,8 ; add one interline
- mov dword ptr edi [edi],0 ; title position
- add edi,4
- row_row:
- stosd
- add eax,ebx
- dec ecx
- jne row_row
- mov eax,200
- pop esi ; restore pixel-lines of text in menu bottom
- sub eax,esi
- mov [edi],eax ; end text position
- ; menu data setup complete
- freshen: ; refresh displayed data
- mov esi,DARK6_TEXT+(DARK6_TEXT shl 8)+(DARK6_TEXT shl 16)+(DARK6_TEXT shl 24)
- mov eax,_VDispX
- mov ecx,40*2
- mov edi,_ScrBase
- mov ebx,25*8
- mov edx,_VDispY
- call _Block ; set background color
- ; NOW WRITE ENTRIES
- mov edx,ENTRIES
- mov esi,offset ENTRY_DATA
- xor eax,eax
- xor ecx,ecx
- add edx,2 ; header & end
- showall:
- mov ebx,[esi]
- add esi,4
- mov al,[ebx] ; get menu entry type
- pushad
- call dword ptr [eax*4+SHOW]
- popad
- inc ecx
- dec edx
- jne showall
- xor eax,eax
- xor edx,edx
- mov ecx,40*2
- mov ebx,25*8
- call _TouchBlock
- call _PageFlip1
- ; and now go for menu animation
- popad
- ret
-
- il_cursore db POINT0,POINT1,0
-
- entry_refresh:
- pushad
- xor eax,eax
- mov ebx,8
- mov edx,[ecx*4+ENTRY_ROW]
- mov ecx,40*2
- call _TouchBlock ; refresh the current entry
- mov eax,_VDispX
- add edx,_VDispY
- mov ebx,offset il_cursore
- mov edi,_ScrBase
- call _PutString ; write cursor
- call _PageFlip1
- popad
- ret
-
- public _PopMenu
-
- _PopMenu:; eax = pointer to menu data
- push _CHRFNT
- pushad
- ; use the "not-input" character set
- INPUT_OFF
- call m_refresh ; refresh/generate the menu data from the description
- mov ecx,1 ; cursor position on first entry
- wazoom: call entry_refresh
- call _WaitKey
- wazaam:
- xor ebx,ebx
- mov edx,[ecx*4+ENTRY_DATA]
- mov bl,[edx] ; get entry type
- cmp byte ptr [eax+_ESC],KPRESSED ; WAIT FOR KEY PRESS&RELEASE
- setnz [eax+_ESC]
- je thee_eend
- cmp byte ptr [eax+_LEFT],KPRESSED
- setnz [eax+_LEFT]
- je decc
- cmp byte ptr [eax+_KMINUS],KPRESSED
- setnz [eax+_KMINUS]
- jne nodec
- decc:
- call [ebx*4+DECREMENT]
- jmp wazoom
- nodec:
- cmp byte ptr [eax+_RIGHT],KPRESSED
- setnz [eax+_RIGHT]
- je incc
- cmp byte ptr [eax+_KPLUS],KPRESSED
- setnz [eax+_KPLUS]
- jne noinc
- incc:
- call [ebx*4+INCREMENT]
- jmp wazoom
- noinc: cmp byte ptr [eax+_UP],KPRESSED
- setnz [eax+_UP]
- jne noo_uup
- call [ebx*4+UPP]
- jmp wazoom
- noo_uup:cmp byte ptr [eax+_DOWN],KPRESSED
- setnz [eax+_DOWN]
- jne noo_dnn
- call [ebx*4+DDN]
- jmp wazoom
- noo_dnn:cmp byte ptr [eax+_ENTER],KPRESSED
- setnz [eax+_ENTER]
- jne wazoom
- call [ebx*4+SELECT]
- test touchngo,01
- jz notouchngo
- call xsel ; trigger menu exit if this is a touch&go menu
- notouchngo:
- call entry_refresh
- rescan:
- call _WaitKey
- test byte ptr [eax+_ENTER],KPRESSED ; do this
- mov byte ptr [eax+_ENTER],0 ;
- jnz rescan ; to avoid key "bounces"
- jmp wazaam
- thee_eend:
- popad
- pop _CHRFNT
- ret
-
- ; Look into 386menu.txt for more info.
- ; This function lets you pop-up and "animate" a menu you defined.
- ; you can select and manipolate menu entry data
- ; using the keyboard
- ;
- ; up/down = change entry
- ; enter = enter a value from the keyboard / trigger entry
- ; (you can do this only one, then you must use another key
- ; before you can "select" the entry again
- ; this is because of the "debouncing" routine)
- ; left,'-' = decrease entry's value
- ; right,'+' = increase entry's value
- ; esc = quit menu (only if menu definition data allows it)
- ;
- ; N.B. It supposed that the calling routine will choose the best method
- ; to save the current screen context before performing the call
- ; and then it will refresh it on return.
-
- code32 ends
- end
-
-
-